home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / delphi.swg / 0083_Another Win-G Inteface for DELPHI.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-11-24  |  15.7 KB  |  479 lines

  1.  
  2. unit WinG;  {WinG import unit for Borland Pascal}
  3. interface
  4. uses winTypes;
  5.  
  6. function WinGCreateDC:hDC;
  7. function WinGRecommendDIBFormat(pFormat:pBitmapInfo):boolean;
  8. function WinGCreateBitmap(WinGDC:hDC; pHeader:pBitmapInfo; var 
  9. ppBits:pointer):hBitmap;
  10. function WinGGetDIBPointer(WinGBitmap:hBitmap; 
  11. pHeader:pBitmapInfo):pointer;
  12. function WinGGetDIBColorTable(WinGDC:hDC; StartIndex, NumberOfEntries:word; 
  13. pColors:pointer):word;
  14. function WinGSetDIBColorTable(WinGDC:hDC; StartIndex, NumberOfEntries:word; 
  15. pColors:pointer):word;
  16.  
  17. function WinGCreateHalftonePalette:hPalette;
  18. type tWinGDither=(winG4x4Dispersed,winG8x8Dispersed,winG4x4Clustered);
  19. function WinGCreateHalftoneBrush(context:hDC; crColor:tColorRef; 
  20. ditherType:tWinGDither):hBrush;
  21.  
  22. function WinGBitBlt(hdcDst:hDC; nXOriginDst, nYOriginDst, nWidthDst, 
  23. nHeightDst:integer;
  24.                     hdcSrc:hDC; nXOriginSrc, nYOriginSrc:integer):boolean;
  25. function WinGStretchBlt(hdcDst:hDC; nXOriginDst, nYOriginDst, nWidthDst, 
  26. nHeightDst:integer;
  27.                         hdcSrc:hDC; nXOriginSrc, nYOriginSrc, nWidthSrc, 
  28. nHeightSrc:integer):boolean;
  29.  
  30. implementation
  31.  
  32. function WinGCreateDC:hDC; external 'WinG';
  33. function WinGRecommendDIBFormat; external 'WinG';
  34. function WinGCreateBitmap; external 'WinG';
  35. function WinGGetDIBPointer; external 'WinG';
  36. function WinGGetDIBColorTable; external 'WinG';
  37. function WinGSetDIBColorTable; external 'WinG';
  38.  
  39. function WinGCreateHalftonePalette; external 'WinG';
  40. function WinGCreateHalftoneBrush; external 'WinG';
  41.  
  42. function WinGBitBlt; external 'WinG';
  43. function WinGStretchBlt; external 'WinG';
  44.  
  45. end.
  46.  
  47. Here is an example of how to implement Delphi with WING..
  48.  
  49. {$A+,B-,D-,F+,G+,I-,K-,L-,N-,P-,Q-,R-,S-,T-,V-,W-,X+,Y-}
  50. {$M 8192,8192}
  51. PROGRAM BPWinG;
  52.  
  53. { - Demonstration of WinG with Borland Pascal
  54.     Written by Lars Fosdal, lfosdal@falcon.no,
  55.  
  56.     Initial version: 11 NOV 1994
  57.     Version 2: 24 NOV 1994
  58.  
  59.     Released to the public domain, 11 NOV 1994
  60.  
  61.     Based on:
  62.       WinG DLL import unit
  63.         by Matthew R Powenski, dv224@cleveland.Freenet.Edu
  64.  
  65.       STATIC - A WinG Sample Application (written in C)
  66.         by Robert B. Hess, Microsoft Corp.
  67.  
  68.       flames.pas from the SWAG libraries (DOS VGA demo)
  69.         by Keith DegrĪ“ce, ekd0840@bosoleil.ci.umoncton.ca.
  70.                        or 9323767@info.umoncton.ca
  71.  
  72.     Note: WinG must be installed before this program can be run.
  73.  
  74.     Hopefully, the latest version of this program can be found as
  75.       garbo.uwasa.fi:/windows/turbopas/bpwing##.zip
  76.     where ## is a version number.
  77.  
  78.     Comments:
  79.       Actually, this is a pretty lame demo (source translated, ideas stolen,
  80.       performance sucks, usability nil), but it shows you the general idea
  81.       of WinG.  On a VL or PCI local bus graphics adapter, the performance
  82.       isn't to bad, but it gets real slow on ISA-only cards.
  83.       In an intelligent WinG app. you don't usually repaint the entire 
  84. bitmap,
  85.       but only the changed sections. You would also tune the bitmap 
  86. generation
  87.       and manipulation routines with assembly, and apply the usual bag of
  88.       animations tricks.
  89.  
  90.       However, thats for you to do!  Have fun!
  91.  
  92.     Changes, Version 2:
  93.      - Range error caused GPF under Win16 (Wonder why it worked under 
  94. Win32/WOW?)
  95.      - Fixed bitmap orientation problem (Didn't work on bottom-up 
  96. oriented bmps)
  97.      - Restructured and added run-time selectable animation style
  98.      - added more comments
  99.  
  100.      And:
  101.        Yep, I know I should have erased the bitmap before I changed the 
  102. palette
  103.        to avoid the "wrong color" flash... You do it :-)
  104.  
  105.     Thanks to:
  106.       Eivind Bakkestuen (hillbilly@programmers.bbs.no)
  107.       for reporting the GPF problem in the initial release.
  108.  
  109.       Timo Salmi, Ari Hovila, and Jouni Ikonen
  110.       for keeping garbo.uwasa.fi a great site to visit.
  111.  
  112. }
  113.  
  114. USES
  115. {$IFDEF Debug}
  116.   WinCRT,
  117. {$ENDIF}
  118.   WinTypes, WinProcs, oWindows, oDialogs, WinG;
  119.  
  120. {$R BPWinG.RES}
  121.  
  122. {.DEFINE x2}  {Stretch to 2 x Size (A _LOT_ Slower :-( )}
  123.  
  124. CONST {Image sizes (flames demo doesn't adapt too well, though)}
  125.   ImageX = 320; {Must be a multiple of two}
  126.   ImageY = 200; {ImageX x ImageY must not exceed 64K}
  127.                 {(Unless you want to write your own array access methods...
  128.                   I _REALLY_ want a 32 bit Pascal :-))}
  129.  
  130. TYPE
  131.   pScreen = ^TScreen; {Bitmap access table}
  132.   TScreen = RECORD
  133.     CASE Integer OF
  134.       0 : (ptb : ARRAY[-(ImageY-1)..0, 0..ImageX-1] OF Byte);
  135.           {ptb = byte coord [y, x]}
  136.       1 : (ptw : ARRAY[-(ImageY-1)..0, 0..(ImageX DIV 2)-1] OF Word);
  137.           {ptw = word coord [y, x div 2]}
  138.       2 : (pta : ARRAY[0..(ImageY*ImageX)-1] OF Byte);
  139.           {pta = byte array [(y*320)+x]}
  140.   END; {REC TScreen}
  141.  
  142.   TImage = RECORD {DIB Information}
  143.     bi       : TBitmapInfoHeader;
  144.     aColors  : ARRAY[0..255] OF TRGBQUAD;
  145.   END; {REC TImage}
  146.  
  147.   TPalette = RECORD {Palette Information}
  148.     Version : Word;         {set to $0300 (Windows version 3.0)}
  149.     NumberOfEntries : Word; {set to 256}
  150.     aEntries : ARRAY[0..255] OF TPaletteEntry;
  151.   END; {REC TPalette}
  152.  
  153.   pWinGApp = ^TWinGApp; {OWL Application}
  154.   TWinGApp = OBJECT(TApplication)
  155.     PROCEDURE InitMainWindow; VIRTUAL;
  156.   END; {OBJ TWinGApp}
  157.  
  158.   pWinGWin = ^TWinGWin; {OWL Window}
  159.   TWinGWin = OBJECT(TWindow)
  160.     LogicalPalette : TPalette; {Our palette initialization table}
  161.     hPalApp    : hPalette; {Our palette}
  162.     Image      : TImage;   {Our bitmap initialization table}
  163.     hdcImage   : hDC;      {Our WinG DC}
  164.     hOldBitmap : hBitmap;  {Ye olde bitmap of the WinG DC must be restored}
  165.     bmp        : pScreen;  {Assistant bitmap pointer}
  166.     Orientation : Integer; {Indicates bitmap orientation,  1=top-down 
  167. -1=bottom-up}
  168.     Direction   : Integer; {Determines animation direction 1=Up       
  169. -1=Down}
  170.     CONSTRUCTOR Init(aParent:pWindowsObject; aTitle:pChar);
  171.     DESTRUCTOR Done;                                   VIRTUAL;
  172.     PROCEDURE GetWindowClass(VAR aWndClass:TWndClass); VIRTUAL;
  173.     PROCEDURE SetupWindow;                             VIRTUAL;
  174.     PROCEDURE SetDirection(NewDirection:Integer);
  175.     PROCEDURE wmEraseBkGnd(VAR Msg:TMessage);          VIRTUAL wm_First + 
  176. wm_EraseBkGnd;
  177.     PROCEDURE wmPaletteChanged(VAR Msg:TMessage);      VIRTUAL wm_First + 
  178. wm_PaletteChanged;
  179.     PROCEDURE wmQueryNewPalette(VAR Msg:TMessage);     VIRTUAL wm_First + 
  180. wm_QueryNewPalette;
  181.     PROCEDURE wmTimer(VAR Msg:TMessage);               VIRTUAL wm_First + 
  182. wm_Timer;
  183.     PROCEDURE Paint(PaintDC:hDC; VAR PaintInfo:TPaintStruct); VIRTUAL;
  184.     PROCEDURE cmAbout(VAR Msg:TMessage);               VIRTUAL cm_First + 
  185. 100;
  186.     PROCEDURE cmQuit(VAR Msg:TMessage);                VIRTUAL cm_First + 
  187. 101;
  188.     PROCEDURE cmDirection(VAR Msg:TMessage);           VIRTUAL cm_First + 
  189. 102;
  190.   END; {OBJ TWinGWin}
  191.  
  192.  
  193. {//////////////////////////////////////////////////////////////// 
  194. TWinGApp ///}
  195.  
  196. PROCEDURE TWinGApp.InitMainWindow;
  197. BEGIN
  198.   MainWindow:=New(pWinGWin, Init(nil, 'WinG + Pascal!'));
  199. END; {PROC TWinGApp.InitMainWindow}
  200.  
  201.  
  202. {//////////////////////////////////////////////////////////////// 
  203. TWinGWin ///}
  204.  
  205. CONSTRUCTOR TWinGWin.Init(aParent:pWindowsObject; aTitle:pChar);
  206. BEGIN
  207.   Inherited Init(aParent, aTitle);
  208.   Attr.Style:=ws_PopupWindow or ws_Caption;
  209.   Attr.x:=160;
  210.   Attr.y:=110;
  211.   Attr.w:={$IFDEF x2}2* {$ENDIF}ImageX + (2 * GetSystemMetrics(sm_CXBorder));
  212.   Attr.h:={$IFDEF x2}2* {$ENDIF}ImageY + (2 * GetSystemMetrics(sm_CYBorder))
  213.                  + GetSystemMetrics(sm_CYCaption)
  214.                  + GetSystemMetrics(sm_CYMenu);
  215.   Attr.Menu:=LoadMenu(hInstance, pChar('WinG_MNU'));
  216.   hPalApp:=0;
  217.   hdcImage:=0;
  218.   hOldBitmap:=0;
  219.   Orientation:=1;
  220.   Direction:=1;
  221. END; {CONS TWinGWin.Init}
  222.  
  223. DESTRUCTOR TWinGWin.Done;
  224. VAR
  225.   hbm : hBitmap;
  226. BEGIN
  227.   IF Bool(hDCImage)                      {If we have a valid DC handle}
  228.   THEN BEGIN
  229.     hbm:=SelectObject(hdcImage, hOldBitmap); {Restore old bitmap}
  230.     DeleteObject(hBM);                       {Delete our bitmap}
  231.     DeleteDC(hdcImage);                      {Delete our DC}
  232.   END;
  233.   IF Bool(hPalApp)                       {If we have a valid palette handle}
  234.   THEN DeleteObject(hPalApp);                {delete our palette}
  235.   KillTimer(hWindow, 1);                 {Kill our timer}
  236.   Inherited Done;                        {Leave the rest to OWL}
  237. END; {DEST TWinGWin.Done}
  238.  
  239. PROCEDURE TWinGWin.GetWindowClass(VAR aWndClass:TWndClass);
  240. BEGIN
  241.   Inherited GetWindowClass(aWndClass);
  242.   aWndClass.hIcon:=LoadIcon(hInstance, pChar('WinG_ICO')); {Load our Icon}
  243.   aWndClass.Style:=cs_ByteAlignClient or cs_VRedraw or cs_HRedraw or 
  244. cs_DblClks;
  245. END; {PROC TWinGWin.GetWindowClass}
  246.  
  247. PROCEDURE TWinGWin.SetupWindow;
  248. VAR
  249.   Desktop     : hDC;     {Get the system colors via the Desktop DC}
  250.   i           : Integer; {general purpose}
  251. BEGIN
  252.   Inherited SetupWindow;             {Let OWL do it's part}
  253.  
  254.   Randomize;
  255.  
  256.   SetTimer(hWindow, 1, 40, nil);     {Create our timer (40ms = 25 
  257. paints/sec)}
  258.   FillChar(Image, SizeOf(Image), 0); {Better safe than sorry}
  259.  
  260.   {Ask WinG about the preferred bitmap format}
  261.   IF WinGRecommendDIBFormat(pBitmapInfo(@Image.Bi))
  262.   THEN BEGIN
  263.     Image.Bi.biBitCount:=8;          {Force to 8 bits per pixel}
  264.     Image.Bi.biCompression:=bi_RGB;  {Force to no compression}
  265.     Orientation:=Image.bi.biHeight;  {Get height}
  266.   END
  267.   ELSE WITH Image.bi              {If WinG failed to initialize our image 
  268. info}
  269.   DO BEGIN                        {we'll do it ourselves}
  270.     biSize:=SizeOf(Image.bi);
  271.     biPlanes:=1;
  272.     biBitCount:=8;
  273.     biCompression:=bi_RGB;
  274.     biSizeImage:=0;
  275.     biClrUsed:=0;
  276.     biClrImportant:=0;
  277.     Orientation:=1;
  278.   END;
  279.  
  280.   Image.bi.biWidth:=ImageX;       {Define the image sizes}
  281.   Image.bi.biHeight:=ImageY * Orientation;
  282.   image.bi.biSizeImage := (image.bi.biWidth * image.bi.biHeight);
  283.   image.bi.biSizeImage := image.bi.biSizeImage*Orientation;
  284.  
  285.   Desktop:=GetDC(0); {Setup our palette init info and get the 20 system 
  286. colors}
  287.   LogicalPalette.Version:=$0300;
  288.   LogicalPalette.NumberOfEntries:=256;
  289.   GetSystemPaletteEntries(Desktop, 0, 10, LogicalPalette.aEntries);
  290.   GetSystemPaletteEntries(Desktop, 246, 10, LogicalPalette.aEntries[246]);
  291.   ReleaseDC(0, Desktop);
  292.  
  293.   FOR i:=0 TO 9  {Duplicate the system colors into the bitmap}
  294.   DO BEGIN
  295.     Image.aColors[i].rgbRed  :=LogicalPalette.aEntries[i].peRed;
  296.     Image.aColors[i].rgbGreen:=LogicalPalette.aEntries[i].peGreen;
  297.     Image.aColors[i].rgbBlue :=LogicalPalette.aEntries[i].peBlue;
  298.     Image.aColors[i].rgbReserved:=0;
  299.     LogicalPalette.aEntries[i].peFlags:=0;
  300.  
  301.     Image.aColors[i+246].rgbRed  :=LogicalPalette.aEntries[i].peRed;
  302.     Image.aColors[i+246].rgbGreen:=LogicalPalette.aEntries[i].peGreen;
  303.     Image.aColors[i+246].rgbBlue :=LogicalPalette.aEntries[i].peBlue;
  304.     Image.aColors[i+246].rgbReserved:=0;
  305.     LogicalPalette.aEntries[i+246].peFlags:=0;
  306.   END;
  307.  
  308.   hdcImage:=WinGCreateDC;                                {Get our WinG DC}
  309.  
  310.   SetDirection(1);
  311.  
  312. END; {PROC TWinGWin.SetupWindow}
  313.  
  314. PROCEDURE TWinGWin.SetDirection(NewDirection:Integer);
  315.   PROCEDURE SetRgb(i,r,g,b:Byte);
  316.   CONST
  317.     c = 4; {Scale up the DOS colors to fit a 24-bit palette}
  318.   BEGIN
  319.     LogicalPalette.aEntries[i].peRed   := r*c;
  320.     LogicalPalette.aEntries[i].peGreen := g*c;
  321.     LogicalPalette.aEntries[i].peBlue  := b*c;
  322.     Image.aColors[i].rgbRed  :=LogicalPalette.aEntries[i].peRed;
  323.     Image.aColors[i].rgbGreen:=LogicalPalette.aEntries[i].peGreen;
  324.     Image.aColors[i].rgbBlue :=LogicalPalette.aEntries[i].peBlue;
  325.     Image.aColors[i].rgbReserved:=0;
  326.     LogicalPalette.aEntries[i].peFlags:=PC_NOCOLLAPSE;
  327.   END;
  328. VAR
  329.   i   : Integer;
  330.   hbm : hBitmap; {Handle to our bitmap}
  331.   mnu : hMenu;
  332. BEGIN
  333.   Direction:=NewDirection;
  334.   mnu:=GetMenu(hWindow);
  335.   IF Direction=1
  336.   THEN BEGIN
  337.     SetWindowText(hWindow,'WinG + Pascal = Hot!');
  338.     ModifyMenu(mnu, 102, mf_ByCommand, 102, 'C&ool!');
  339.     FOR i := 1 TO 32 {Build Black->Red->Yellow->White colors}
  340.     DO BEGIN
  341.      SetRgb(i, (i shl 1)-1, 0, 0 );
  342.      SetRgb(i+32, 63, (i shl 1)-1, 0 );
  343.      SetRgb(i+64, 63, 63, (i shl 1)-1 );
  344.      SetRgb(i+96, 63, 63, 63 );
  345.     END
  346.   END
  347.   ELSE BEGIN
  348.     SetWindowText(hWindow,'WinG + Pascal = Cool!');
  349.     ModifyMenu(mnu, 102, mf_ByCommand, 102, 'H&ot!');
  350.     FOR i := 1 TO 32 {Build Black->Blue->Cyan->White colors}
  351.     DO BEGIN
  352.      SetRgb(i, 0, 0, (i shl 1)-1);
  353.      SetRgb(i+32,  0, (i shl 1)-1, 63 );
  354.      SetRgb(i+64, (i shl 1)-1, 63, 63 );
  355.      SetRgb(i+96, 63, 63, 63 );
  356.     END;
  357.   END;
  358.   DrawMenuBar(hWindow);
  359.  
  360.   IF Bool(hOldBitmap)
  361.   THEN BEGIN
  362.     DeleteObject(hPalApp);
  363.     DeleteObject(SelectObject(hDCImage, hOldBitmap));
  364.   END;
  365.   hPalApp:=CreatePalette(pLogPalette(@LogicalPalette)^);
  366.   hBM:=WinGCreateBitmap(hdcImage, pBitmapInfo(@Image.Bi), @bmp);
  367.  
  368.   hOldBitmap:=SelectObject(hdcImage, hBM); {Associate the bitmap with the DC}
  369.  
  370.   PatBlt(hDCImage, 0,0, ImageX, ImageY, BLACKNESS); {Paint the bitmap black}
  371.   InvalidateRect(hWindow, nil, True);
  372. END; {PROC TWinGWin.SetDirection}
  373.  
  374. PROCEDURE TWinGWin.wmEraseBkGnd(VAR Msg:TMessage);
  375. BEGIN
  376.   Bool(Msg.Result):=True; {We don't want Windows to erase our background}
  377. END; {FUNC TWinGWin.wmEraseBkGnd}
  378.  
  379. PROCEDURE TWinGWin.wmPaletteChanged(VAR Msg:TMessage);
  380. BEGIN                           {If some other Windows app has focus and 
  381. changed}
  382.   IF Msg.wParam=hWindow         {the system colors, we'll update too so 
  383. that we}
  384.   THEN wmQueryNewPalette(Msg);  {can get the second best choices}
  385. END; {PROC TWinGWin.wmPaletteChanged}
  386.  
  387. PROCEDURE TWinGWin.wmQueryNewPalette(VAR Msg:TMessage);
  388. { - Update palette and repaint if changed}
  389. VAR
  390.   DC : hDC;
  391.   ReMappedColors:Word;
  392. BEGIN
  393.   DC:=GetDC(hWindow);
  394.   IF Bool(hPalApp)
  395.   THEN SelectPalette(DC, hPalApp, False);
  396.   ReMappedColors:=RealizePalette(DC);
  397.   ReleaseDC(hWindow, DC);
  398.   IF (ReMappedColors > 0)
  399.   THEN BEGIN
  400.     InvalidateRect(hWindow, nil, True);
  401.     Bool(Msg.Result):=True;
  402.   END
  403.   ELSE Bool(Msg.Result):=False;
  404. END; {PROC TWinGWin.wmQueryNewPalette}
  405.  
  406. PROCEDURE TWinGWin.wmTimer(VAR Msg:TMessage);
  407. BEGIN
  408.   InvalidateRect(hWindow, nil, False); {Force a repaint}
  409. END; {PROC TWinGWin.wmTimer}
  410.  
  411. PROCEDURE TWinGWin.Paint(PaintDC:hDC; VAR PaintInfo:TPaintStruct);
  412. VAR
  413.   x,y,
  414.   x2,y2,c : Integer;
  415.   one, two : Integer;
  416. BEGIN
  417.   SelectPalette(PaintDC, hPalApp, False); {Select our palette}
  418.   RealizePalette(PaintDC);                {and map it to the system palette}
  419.   IF not Assigned(bmp)
  420.   THEN Exit;
  421.   WITH bmp^         {With our bitmap bits}
  422.   DO BEGIN
  423.     one:=1*Orientation*Direction;
  424.     two:=2*Orientation*Direction;
  425.     FOR x := 0 TO 159  {Update the flame bitmap}
  426.     DO BEGIN
  427.       x2:=x shl 1;
  428.       FOR y := 30 TO 98
  429.       DO BEGIN
  430.         IF Orientation=Direction
  431.         THEN y2:=-(y shl 1)
  432.         ELSE y2:=-200+(y shl 1);
  433.         c := (ptb[y2,x2]
  434.             + ptb[y2,x2+2]
  435.             + ptb[y2,x2-2]
  436.             + ptb[y2-two,x2+2]) shr 2;
  437.         IF c <> 0 THEN dec(c);
  438.         ptw[y2+two, x] := Word(c or (c shl 8));
  439.         ptw[y2+one, x] := Word(c or (c shl 8));
  440.       END;
  441.       ptb[y2,x2] := random(2)*160;
  442.     END;
  443.   END;
  444. {$IFDEF x2}
  445.   WinGStretchBlt(PaintDC, 0,0, 2*ImageX, 2*ImageY, hdcImage, 0,0, ImageX, 
  446. ImageY);
  447. {$ELSE}
  448.   WinGBitBlt(PaintDC, 0,0, ImageX, ImageY, hdcImage, 0,0);
  449. {$ENDIF}
  450. END; {PROC TWinGWin.Paint}
  451.  
  452. PROCEDURE TWinGWin.cmAbout(VAR Msg:TMessage);
  453. VAR
  454.   Dlg : pDialog;
  455. BEGIN
  456.   New(Dlg, Init(@Self, pChar('WinG_DLG')));
  457.   Dlg^.Execute;
  458.   Dispose(Dlg, Done);
  459. END; {PROC TWinGWin.cmAbout}
  460.  
  461. PROCEDURE TWinGWin.cmDirection(VAR Msg:TMessage);
  462. BEGIN
  463.   SetDirection(-Direction);
  464. END; {PROC TWinGWin.cmDirection}
  465.  
  466. PROCEDURE TWinGWin.cmQuit(VAR Msg:TMessage);
  467. BEGIN
  468.   CloseWindow;
  469. END; {PROC TWinGWin.cmQuit}
  470.  
  471. VAR
  472.   App : pWinGApp;
  473. BEGIN
  474.   New(App, Init('BPWinG'));
  475.   App^.Run;
  476.   Dispose(App, Done);
  477. END.
  478.  
  479.